<?php


class Tool_Check
{

    /**
     * ----将下划线命名的函数,改为驼峰命名
     * 例如 "call_user_func_array" 处理成 ''CallUserFuncArray    'user_id_Ho' => 'UserIdHo'
     * @param $str
     * @return string
     */
    public static function changeStr($str)
    {
        $str_array = explode('_', $str);
        $arr_ucfirst = array_map(function($v) {
            return ucfirst($v);
        }, $str_array);

        return implode('', $arr_ucfirst);
    }

    /**
     * ----对整数字符串进行排序  '34198301483' => '01133344889'
     * @param $srt
     * @return string
     */
    public static function sortStr($srt)
    {
        $str_int_arr = str_split($srt);
        sort($str_int_arr);
        return implode('', $str_int_arr);
    }

    /**
     * ----验证18位身份证号码的合法性
     * @param $id_card
     * @return bool
     */
    public static function CheckIsIDCard($id_card)
    {
        if(mb_strlen($id_card) != 18) {
            return false;
        }
        //校验位列表
        $remainder_list = [1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2];
        //加权除以11的余数
        $square_remainder = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        //取得身份证号码最后一位校验位
        $check_num = mb_substr($id_card, 17);
        //身份证参与校验的前17位
        $id_card = mb_substr($id_card, 0, 17);
        //参与校验的必须是数字
        if(!is_numeric($id_card)) {
            return false;
        }
        $square_sum = 0;//每一位参与校验数乘以加权数的累加和
        $number_sum = 0;//每一位参与校验数乘以加权除以11的余数的累加和
        for ($i = 0; $i < 17; $i++){
            //累加结果
            $square_sum += intval($id_card[$i]) * pow(2, 17 - $i);
            //累加结果
            $number_sum += intval($id_card[$i]) * $square_remainder[$i];
        }

        //从校验位列表中获取加权乘积和得到的校验位
        $check_get_square_remainder = isset($remainder_list[$square_sum % 11]) ? $remainder_list[$square_sum%11] : -1;
        //从校验位列表中获取加权余数乘积和得到的校验位
        $check_get_number_remainder = isset($remainder_list[$number_sum % 11]) ? $remainder_list[$number_sum % 11] : -1;

        if($check_get_square_remainder == $check_num && $check_get_number_remainder == $check_num) {
            return true;
        }

        return false;
    }

    /**
     * 高精度计算函数
     * @param string $method 方法  add、sub、mul、div
     * @param double $left_operand 左操作符
     * @param double $right_operand 右操作符
     * @param int $scale 小数位数
     * @param bool $is_round 是否四舍五入
     * @return double
     */
    public static function BcCalc($method,$left_operand,$right_operand,$scale = 2,$is_round = false)
    {
        if(!function_exists('bcadd')){
            throw new \Exception('没有高精度计算函数！');
        }
        switch ($method){
            case 'add' :
                if($is_round) {
                    return round(bcadd((float)$left_operand,(float)$right_operand,$scale+1), $scale);
                } else {
                    return bcadd((float)$left_operand,(float)$right_operand,$scale);
                }
                break;
            case 'sub':
                if($is_round) {
                    return round(bcsub((float)$left_operand,(float)$right_operand,$scale+1), $scale);
                } else {
                    return bcsub((float)$left_operand,(float)$right_operand, $scale);
                }
                break;
            case 'mul' :
                if($is_round){
                    return round(bcmul((float)$left_operand,(float)$right_operand,$scale+1), $scale);
                } else {
                    return bcmul((float)$left_operand,(float)$right_operand,$scale);
                }
                break;
            case 'div':
                if($is_round){
                    return round(bcdiv((float)$left_operand,(float)$right_operand,$scale+1), $scale);
                } else {
                    return bcdiv((float)$left_operand,(float)$right_operand, $scale);
                }
                break;
            default : throw new \Exception('未知计算方式'); break;
        }
    }
}
